
#include "Parameter.hpp"
#include "Exception.hpp"

namespace VoodooShader
{
	Parameter::Parameter(CGparameter param)
		: mParam(param), mType(cgGetParameterType(param))
	{ 
		switch ( this->mType )
		{
		case CG_SAMPLER:
		case CG_SAMPLER1D:
		case CG_SAMPLER2D:
		case CG_SAMPLER3D:
		case CG_SAMPLERCUBE:
			this->mValueTexture = NULL;
			break;
		case CG_FLOAT4:
			this->mValueFloat[3] = 0.0f;
		case CG_FLOAT3:
			this->mValueFloat[2] = 0.0f;
		case CG_FLOAT2:
			this->mValueFloat[1] = 0.0f;
		case CG_FLOAT1:
		case CG_FLOAT:
			this->mValueFloat[0] = 0.0f;
			break;
		default:
			//! @todo Fix this, shouldn't Throw with a NULL Core
			Throw("Invalid parameter type.", NULL);
		}
	}

	CGparameter Parameter::Parameter(void)
	{
		return this->mParam;
	}

	CGtype Parameter::Type(void)
	{
		return this->mType;
	}

	void Parameter::Set(Texture * newTex)
	{
		this->mValueTexture = newTex;
	}

	void Parameter::Set(float newX)
	{
		this->mValueFloat[0] = newX;
	}

	void Parameter::Set(float newX, float newY)
	{
		this->mValueFloat[0] = newX;
		this->mValueFloat[1] = newY;
	}

	void Parameter::Set(float newX, float newY, float newZ)
	{
		this->mValueFloat[0] = newX;
		this->mValueFloat[1] = newY;
		this->mValueFloat[2] = newZ;
	}

	void Parameter::Set(float newX, float newY, float newZ, float newW)
	{
		this->mValueFloat[0] = newX;
		this->mValueFloat[1] = newY;
		this->mValueFloat[2] = newZ;
		this->mValueFloat[3] = newW;
	}

	void Parameter::Get(Texture ** param)
	{
		// Hooray for **! Funny how it can actually be useful, even if it's almost
		// as dirty as goto.
		*param = this->mValueTexture;
	}

	void Parameter::Get(float & paramX)
	{
		paramX = this->mValueFloat[0];
	}

	void Parameter::Get(float & paramX, float & paramY)
	{
		paramX = this->mValueFloat[0];
		paramY = this->mValueFloat[1];
	}

	void Parameter::Get(float & paramX, float & paramY, float & paramZ)
	{
		paramX = this->mValueFloat[0];
		paramY = this->mValueFloat[1];
		paramZ = this->mValueFloat[2];
	}

	void Parameter::Get(float & paramX, float & paramY, float & paramZ, float & paramW)
	{
		paramX = this->mValueFloat[0];
		paramY = this->mValueFloat[1];
		paramZ = this->mValueFloat[2];
		paramW = this->mValueFloat[3];
	}
}